package com.simafei.flow.core;

import com.simafei.flow.core.common.ExecStatus;
import com.simafei.flow.core.common.FlowStatus;
import com.simafei.flow.core.common.NodeType;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;

/**
 * @author fengpengju
 */
public class ManualNode extends Node {

    public ManualNode() {
        super(NodeType.MANUAL);
    }

    @Override
    protected NodeResult executeWithHandling(ExecutionContext context, List<Map<String, Object>> params, String parentId) {
        // 查看该节点的执行记录
        Optional<NodeResult> executed = context.getNodeResults().stream()
                .filter(nodeResult -> nodeResult.getNodeId().equals(getId())).findFirst();

        ExecStatus execStatus = ExecStatus.RUNNING;
        boolean success = true;
        if (executed.isEmpty()) {
            // 没有执行过，初次执行，状态设为等待状态
            execStatus = ExecStatus.WAITING;
        } else if (ExecStatus.WAITING == executed.get().getExecStatus()) {
            // 如果执行过，并且状态是等待状态，则恢复执行
            execStatus = ExecStatus.FINISHED;
            success = context.getFlowStatus() != FlowStatus.REJECT;
        }
        return NodeResult.builder()
                .name(getName())
                .nodeId(getId())
                .nodeType(getNodeType())
                .success(success)
                .inputParams(params)
                .startTime(System.currentTimeMillis())
                .results(doExecute(context, params))
                .execStatus(execStatus)
                .flowStatus(context.getFlowStatus())
                .endTime(System.currentTimeMillis())
                .parentId(parentId)
                .build();
    }

    @Override
    protected List<ExecutionResult> doExecute(ExecutionContext context, List<Map<String, Object>> params) {
        Map<String, Object> attributes = context.getAttributes(getId());

        return params.stream().map(param -> ExecutionResult.builder()
                .inputParams(param)
                .results(Objects.nonNull(attributes) ? List.of(attributes) : List.of())
                .build()).toList();
    }
}
